/**
 * 提供操作pcd的接口
*/
#ifndef _RC522_PCD_H_
#define _RC522_PCD_H_

#include <stdint.h>

/**
 * @brief 复位RC522
*/
void pcd_reset(void);

/**
 * @brief 开启天线
 * @return 无
*/
void pcd_antenna_on(void);

/**
 * @brief 关闭天线
 * @return 无
*/
void pcd_antenna_off(void);

/**
 * pcd通讯返回错误代码
*/
typedef enum {
	PCD_OK,
	PCD_NOTAGERR,
	PCD_ERR,
} pcd_err_t;

/**
 * @brief 通过MFRC522和ISO14443卡通讯
 * @param command -[in] RC522命令字
 * @param send_data -[in] 通过RC522发送到卡片的数据
 * @param send_data_len_byte -[in] 发送数据的字节长度
 * @param recv_data -[out] 接收到的卡片返回数据
 * @param recv_data_len_bit -[out] 返回数据的位长度
 * @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_com_with_picc(uint8_t command, uint8_t *send_data,
			    uint8_t send_data_len_byte, uint8_t *recv_data,
			    uint32_t *recv_data_len_bit);

/**
 * @brief 寻卡
 * @param req_code -[in] 寻卡方式，0x52 寻感应区内所有符合1443A标准的卡，0x26 寻未进入休眠状态的卡
 * @param tag_type -[out] 卡片类型代码
 *      0x4400 = Mifare_UltraLight
 *      0x0400 = Mifare_One(S50)
 *      0x0200 = Mifare_One(S70)
 *      0x0800 = Mifare_Pro(X)
 *      0x4403 = Mifare_DESFire
 * @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_request(uint8_t req_code, uint8_t *tag_type);

/**
 @brief 防冲撞
 @param serial_num -[out] 卡片序列号，4字节
 @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_anticoll(uint8_t *serial_num);

/**
 @brief 用MF522计算CRC16
 @param input -[in] 计算CRC16的数组
 @param len -[in] 计算CRC16的数组字节长度
 @param output -[out] 存放计算结果存放的首地址
 @return 无
*/
void pcd_calc_crc(const uint8_t *input, uint8_t len, uint8_t *output);

/**
 @brief 选定卡片
 @param serial_num -[in] 卡片序列号，4字节
 @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_select(const uint8_t *serial_num);

/**
 @brief 验证卡片密码
 @param auth_mode -[in] 密码验证模式，0x60 验证A密钥，0x61 验证B密钥
 @param addr -[in] 块地址
 @param key -[in] 密码
 @param serial_num -[in] 卡片序列号，4字节
 @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_auth(uint8_t auth_mode, uint8_t addr, const uint8_t *key,
		   const uint8_t *serial_num);

/**
 @brief 读取M1卡一块数据
 @param addr -[in] 块地址
 @param data -[out] 读出的数据，16字节
 @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_read(uint8_t addr, uint8_t data[16]);

/**
 @brief 写入M1卡一块数据
 @param addr -[in] 块地址
 @param data -[out] 写入的数据，16字节
 @return 状态值，MI OK - 成功；MI_ERR - 失败
*/
pcd_err_t pcd_write(uint8_t addr, const uint8_t data[16]);

#endif